﻿using AutoMapper;
using ProjectManageSystemApi.DbEntity;
using ProjectManageSystemApi.Enums;
using ProjectManageSystemApi.Models;
using ProjectManageSystemApi.Utilities;
using System;
using System.Collections.Generic;

namespace ProjectManageSystemApi.Services.Impl
{
    public class ProjectInfoServices : IProjectInfoServices
    {
        readonly IFreeSql _fsql;
        readonly IMapper _mapper;
        readonly IProjectUserInfoServices _projectUser;
        public ProjectInfoServices(IFreeSql fsql, IMapper mapper, IProjectUserInfoServices projectUser)
        {
            _fsql = fsql;
            _mapper = mapper;
            _projectUser = projectUser;
        }

        public bool Create(ProjectInfoDto project)
        {
            try
            {
                _fsql.Transaction(() =>
                    {
                        var data = _mapper.Map<ProjectInfo>(project);
                        data.CreateTime = DateTime.Now.GetMillUtcTimeStamp();
                        data.State = (int)ProjectInfoState.Default;
                        int projectId = (int)_fsql.Insert<ProjectInfo>(data).ExecuteIdentity();
                        if (projectId <= 0)
                        {
                            throw new DbTranException("增加工程失败");
                        }
                        var userInfo = new ProjectUserIdDto
                        {
                            ProjectId = projectId,
                            UserId = project.CreateUser
                        };
                        // 可以防止增加工程后没权限查看
                        if (!_projectUser.Insert(userInfo, project.CreateUser))
                        {
                            throw new DbTranException("增加工程人员失败");
                        }
                    });
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool Update(ProjectInfoDto project)
        {
            var data = _mapper.Map<ProjectInfo>(project);
            return _fsql.Update<ProjectInfo>().SetSource(data).IgnoreColumns(x => new { x.CreateTime, x.CreateUser, x.State }).ExecuteAffrows() > 0;
        }

        /// <summary>
        /// 修改状态值
        /// </summary>
        public bool UpdateState(int id, ProjectInfoState state)
        {
            return _fsql.Update<ProjectInfo>(id).Set(x => x.State, (sbyte)state).ExecuteAffrows() > 0;
        }

        /// <summary>
        /// admin 可以看到所有的项目和工程
        /// </summary>
        /// <param name="pageBo"></param>
        /// <returns></returns>
        public Models.PageVo<List<ProjectInfoDto>> GetAll(Models.PageBo<ProjectInfoParams> pageBo)
        {
            var data = _fsql.Select<ProjectInfo>()
                .Where(x=> x.State > (int)ProjectInfoState.Delete)
                .OrderBy(x => x.State)
                .OrderByDescending(x => x.CreateTime);
            if (pageBo.Param != null && !string.IsNullOrWhiteSpace(pageBo.Param.Name))
            {
                data = data.Where(x => x.ProjectName.Contains(pageBo.Param.Name));
            }
            var count = data.Count();
            data = data.Page(pageBo.Page, pageBo.Size);
            return new Models.PageVo<List<ProjectInfoDto>>
            {
                Page = pageBo.Page,
                Size = pageBo.Size,
                Total = count,
                Datas = _mapper.Map<List<ProjectInfoDto>>(data.ToList())
            };
        }

        /// <summary>
        /// 项目经理和施工人员 只能看到分配后的项目和工程
        /// </summary>
        /// <returns></returns>
        public Models.PageVo<List<ProjectInfoDto>> GetByUserId(long userId, Models.PageBo<ProjectInfoParams> pageBo)
        {
            var data = _fsql.Select<ProjectInfo>()
                .Where(x => _fsql.Select<ProjectUserInfo>().Any(y => y.UserId == userId && x.Id == y.ProjectId 
                    && y.Status == (byte)ProjectUserInfoStatus.Default))
                .Where(x=>x.State > (int)ProjectInfoState.Delete)
                .OrderBy(x=> x.State)
                .OrderByDescending(x=> x.CreateTime);
            if (pageBo.Param != null && !string.IsNullOrWhiteSpace(pageBo.Param.Name))
            {
                data = data.Where(x => x.ProjectName.Contains(pageBo.Param.Name));
            }
            var count = data.Count();
            data = data.Page(pageBo.Page, pageBo.Size);
            return new Models.PageVo<List<ProjectInfoDto>>
            {
                Page = pageBo.Page,
                Size = pageBo.Size,
                Total = count,
                Datas = _mapper.Map<List<ProjectInfoDto>>(data.ToList())
            };
        }

        /// <summary>
        /// 判断是否名字重复
        /// </summary>
        public bool HasExistName(string name, int id = 0)
        {
            return _fsql.Select<ProjectInfo>().Any(x => x.Id != id && x.ProjectName == name && x.State > (int)ProjectInfoState.Delete);
        }
        public int AddAndGetIdByName(string name, long createUser)
        {
            var project = _fsql.Select<ProjectInfo>().Where(x => x.ProjectName == name && x.State > (int)ProjectInfoState.Delete).ToOne();
            if(project != null) 
            {
                return project.Id;
            }
            try
            {
                int projectId = 0;
                _fsql.Transaction(() =>
                {
                    project = new ProjectInfo 
                    {
                        ProjectName = name,
                        CreateUser = createUser,
                        CreateTime = DateTime.Now.GetMillUtcTimeStamp(),
                        State = (int)ProjectInfoState.Default
                    };
                    projectId = (int)_fsql.Insert<ProjectInfo>(project).ExecuteIdentity();
                    if (projectId <= 0)
                    {
                        throw new DbTranException("增加工程失败");
                    }
                    var userInfo = new ProjectUserIdDto
                    {
                        ProjectId = projectId,
                        UserId = project.CreateUser
                    };
                    // 可以防止增加工程后没权限查看
                    if (!_projectUser.Insert(userInfo, project.CreateUser))
                    {
                        throw new DbTranException("增加工程人员失败");
                    }
                });
                return projectId;
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// 判断是否存在该Id
        /// </summary>
        public bool HasExistId(int id) 
        {
            return _fsql.Select<ProjectInfo>().Any(x=> x.Id == id && x.State > (int)ProjectInfoState.Delete);
        }

        /// <summary>
        /// 判断是否已经完成，已完成数据不允许修改
        /// </summary>
        public bool IsFinish(int id)
        {
            return _fsql.Select<ProjectInfo>().Any(x => x.Id == id && x.State == (int)ProjectInfoState.Finish);
        }
    }
}
